<template>
  <div class="menu-permission">
    <el-checkbox style="margin-left:19%" v-model="menuExpand" @change="handleCheckedTreeExpand">展开/折叠</el-checkbox>
    <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll">全选/全不选</el-checkbox>
    <!-- <el-checkbox v-model="menuCheckStrictly" @change="handleCheckedTreeConnect">父子联动</el-checkbox> -->
    <el-tree
      ref="menuRef"
      class="tree-border"
      :data="menuOptions"
      show-checkbox
      node-key="id"
      :check-strictly="!menuCheckStrictly"
      empty-text="加载中，请稍候"
      :props="{ label: 'name', children: 'children' } as any"
      @check="handleCheck"
    ></el-tree>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue';
import type { ElTreeInstance } from 'element-plus';
import type { MenuTreeOption } from '@/api/system/menu/types';

const props = defineProps<{
  modelValue?: number[],  // 修改为数组类型
  menuOptions: MenuTreeOption[]
}>();

const emit = defineEmits<{
  (e: 'update:modelValue', value: number[]): void;  // 修改为数组类型
  (e: 'change', value: number[]): void;  // 添加 change 事件
}>();

const menuRef = ref<ElTreeInstance>();
const menuExpand = ref(false);
const menuNodeAll = ref(false);
const menuCheckStrictly = ref(true);


/** 树权限（展开/折叠）*/
const handleCheckedTreeExpand = (value: boolean) => {
  const treeList = props.menuOptions;
  for (let i = 0; i < treeList.length; i++) {
    if (menuRef.value) {
      menuRef.value.store.nodesMap[treeList[i].id].expanded = value;
    }
  }
};

/** 树权限（全选/全不选） */
const handleCheckedTreeNodeAll = (value: boolean) => {
  menuRef.value?.setCheckedNodes(value ? props.menuOptions : []);
  // 手动触发 check 事件以更新值和触发校验
  handleCheck();
};

/** 树权限（父子联动） */
const handleCheckedTreeConnect = (value: boolean) => {
  menuCheckStrictly.value = value;
  emit('update:modelValue', value);
};

/** 获取所有选中的菜单节点 */
const getMenuAllCheckedKeys = (): number[] => {
  // 目前被选中的菜单节点
  const checkedKeys = menuRef.value?.getCheckedKeys() || [];
  // 半选中的菜单节点
  const halfCheckedKeys = menuRef.value?.getHalfCheckedKeys() || [];
  checkedKeys.push(...halfCheckedKeys);
  return checkedKeys as number[];
};

/** 设置选中节点 */
const setCheckedKeys = (keys: number[]) => {
  nextTick(() => {
    keys.forEach((key) => {
      menuRef.value?.setChecked(key, true, false);
    });
  });
};

/** 重置选中状态 */
const reset = () => {
  menuRef.value?.setCheckedKeys([]);
  menuExpand.value = false;
  menuNodeAll.value = false;
};

defineExpose({
  getMenuAllCheckedKeys,
  setCheckedKeys,
  reset
});

/** 处理节点选中状态变化 */
const handleCheck = () => {
  const checkedKeys = getMenuAllCheckedKeys();
  emit('update:modelValue', checkedKeys);
  emit('change', checkedKeys);
};
</script>

<style scoped>
.tree-border {
  margin-top: 5px;
  border: 1px solid var(--el-border-color);
  padding: 10px;
  border-radius: 4px;
}
.menu-permission {
  width: 100%;
}
</style>
